home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
assemblr
/
library
/
sampler0
/
keymod.asm
< prev
next >
Wrap
Assembly Source File
|
1986-03-01
|
10KB
|
401 lines
cseg segment para public 'code'
org 100h
keymod proc far
keyaddr equ 9h*4 ; keyboard interrupt address
vidaddr equ 10h*4 ; video interrupt address
usraddr equ 61h*4 ; user interrupt address
whozat equ 1235h ; signature value
; Memory-resident program to intercept keyboard interrupts.
; Once loaded, this program will remain resident until DOS is reloaded.
; The program can be re-run, to change the original options.
; This program is used to control the state of the following keys:
;
; Caps Lock : U+ (force on), U- (force off), or U (normal)
; Num Lock : N+ (force on), N- (force off), or N (normal)
; Alt Key : A+ (force on), A- (force off), or A (normal)
; Ctrl Key : C+ (force on), C- (force off), or C (normal)
; Left Shift : L+ (force on), L- (force off), or L (normal)
; Right Shift: R+ (force on), R- (force off), or R (normal)
; Boot : B+ or B (on - normal) or B- (off - disabled)
; Ctrl-Break : X+ or X (on - normal) or X- (off - disabled)
; Suspend : S+ (enable pause), S- or S (normal - no effect)
; Reset all keys to normal: *
;
; For example, 'KEYMOD U+ B- X-' would force caps lock on, disable booting via
; Alt-Ctrl-Del, and disable Ctrl-Break.
assume cs:cseg,ds:cseg,ss:nothing,es:nothing
jmp p100 ; start-up code
keyint dd 0 ; keyboard interrupt vector
vidint dd 0 ; video interrupt vector
signature dw whozat ; program's signature
; keyboard mod table
; 0 = no change, 1 = force off, 2 = force on
modtbl db 0ffh ; insert - not used
db 0 ; caps lock
db 0 ; num lock
db 0ffh ; suspend - used below
db 0 ; alt
db 0 ; ctrl
db 0 ; left shift
db 0 ; right shift
noboot db 0 ; disable boot if 1
nobreak db 0 ; disable ctrl-break if 1
suspend db 0 ; enable suspend key if 2
tstack db 16 dup ('stack ') ; temporary stack
estack db 0 ; end of temp stack
holdss dw 0 ; original ss
holdsp dw 0 ; original sp
p000: sti ; interrupt (resident) code starts here
push ax ; save registers
push cx
push es
push di
pushf
mov ax,40h
mov es,ax
mov di,17h ; point to keyboard flag
mov ah,es:[di] ; keyboard state - flag in ah
mov cx,8
mov di,offset modtbl ; point to mod table
p010: mov al,cs:[di] ; get mod value
cmp al,1 ; turn key off?
jz p020 ; yes
cmp al,2 ; turn key on?
jz p015 ; yes
jmp p030 ; do nothing with this one
p015: mov al,1 ; turn key on
rol al,cl ; rotate left
ror al,1 ; back 1
or ah,al ; switch bits on in ah
jmp p030
p020: mov al,1 ; turn key off
rol al,cl
ror al,1
xor al,0ffh ; flip the bits
and ah,al ; switch bits off in ah
p030: inc di
loop p010 ; continue
mov al,cs:[noboot] ; is boot disabled?
cmp al,1
jnz p040 ; no
test ah,08h ; alt pressed?
jz p040 ; no
test ah,04h ; ctrl pressed?
jz p040 ; no
and ah,0fbh ; tried alt-ctrl-del, turn off ctrl!
p040: test ah,04h ; is ctrl pressed?
jz p050 ; no
mov al,cs:[nobreak] ; is ctrl-break disabled?
cmp al,1
jnz p050 ; no
in al,60h ; get next char from kybd
cmp al,46 ; is it a 'c'?
jz p045 ; yes
cmp al,70 ; is it a break?
jz p045 ; yes
jmp p050
p045: and ah,0fbh ; turn off ctrl!
p050: mov di,17h
mov es:[di],ah
popf
pop di
pop es
pop cx
pop ax
jmp cs:[keyint]
p060: sti ; resident code for video interrupt
push ax ; save registers
push di
push es
mov al,cs:[suspend] ; is suspend on?
cmp al,2
jnz p070 ; no
mov di,40h
mov es,di
mov di,17h ; point to keyboard flag
mov al,es:[di] ; get keyboard flag
test al,10h ; check suspend
jz p070 ; it's off
cmp ah,7 ; scroll down?
jz p065 ; yes
cmp ah,6 ; scroll up?
jnz p070 ; no
p065:
cli ; no interrupts
mov ax,ss ; save original stack
mov cs:[holdss],ax
mov cs:[holdsp],sp
mov ax,cs ; point to temp stack
mov ss,ax ; make ss=cs
mov sp,offset estack
sti ; allow interrupts
mov ah,0 ; wait for a key to be pressed
int 16h
cli ; no interrupts
mov ax,cs:[holdss] ; restore original stack
mov ss,ax
mov sp,cs:[holdsp]
sti ; allow interrupts
mov di,17h
mov al,es:[di] ; keyboard state - flag in al
and al,0efh ; turn suspend off
mov es:[di],al ; re-set state
p070: pop es
pop di
pop ax
jmp cs:[vidint] ; jump to video interrupt
p100: ; transient code starts here
call p120 ; get current keyboard vector
call p140 ; decode command line
call p160 ; turn suspend off
call p180 ; display key settings
mov al,firstime
cmp al,1 ; first time?
jz p105 ; yes - leave resident
int 20h ; no - vanish!
p105: mov dx,offset p100 ; last byte of resident portion
int 27h ; terminate
p120 proc near ; get current keyboard buffer
mov dx,offset copyr
call p200 ; display copyright
mov di,usraddr+2 ; point to user interrupt
mov ax,0
mov es,ax
mov bx,es:[di] ; get current contents
mov es,bx ; make it the segment
mov di,offset signature
mov cx,es:[di] ; get signature
cmp cx,whozat ; is it this program?
jz p125 ; yes - don't install it
mov ax,0
mov es,ax
mov di,keyaddr ; point to keyboard interrupt
mov ax,es:[di] ; get current ip
mov bx,es:[di+2] ; get current cs
mov si,offset keyint ; save address
mov [si],ax
mov [si+2],bx
mov di,vidaddr ; point to video interrupt
mov ax,es:[di] ; get current ip
mov bx,es:[di+2] ; get current cs
mov si,offset vidint ; save address
mov [si],ax
mov [si+2],bx
mov al,1 ; first time through
mov firstime,al ; set first time flag
mov dx,offset install
call p200
mov ax,0
mov es,ax
mov bx,ds
cli ; no interrupts
mov di,keyaddr
mov ax,offset p000
mov es:[di],ax ; change keyboard interrupt
mov es:[di+2],bx
mov di,vidaddr
mov ax,offset p060
mov es:[di],ax ; change video interrupt
mov es:[di+2],bx
mov di,usraddr ; set user interrupt - segment only
mov ax,offset signature
mov es:[di],ax
mov es:[di+2],bx
sti ; allow interrupts again
push cs
pop bx ; get current cs
p125: mov si,offset realcs
mov [si],bx ; save real cs
ret
p120 endp
p140 proc near ; decode command line
mov si,80h ; point to command line
mov ch,0
mov cl,[si] ; get length
jcxz p159 ; length is zero
push cx ; save length
inc si ; point to first char
push si ; save start addr
p142: mov al,[si] ; get character
cmp al,'a' ; lower case?
jb p144 ; no
cmp al,'z' ; lower case?
ja p144 ; no
sub al,'a'-'A' ; yes - make it upper case
mov [si],al ; put it back on the line
p144: inc si ; point to next
loop p142 ; all done?
mov ax,realcs
mov es,ax
pop bx ; get start addr
pop cx ; get command line length
p146: mov al,[bx] ; get character
cmp al,' ' ; is it a space?
jz p155 ; yes
cmp al,'*' ; is it an asterisk?
jz p146a ; yes
cmp al,'8' ; is it an 8 (lower-case asterisk)?
jz p146a ; yes
jmp p146b
p146a: mov di,offset modtbl ; clear all key modifications
mov cx,11
mov al,0
rep stosb ; clear mod table
jmp p159 ; return
p146b: mov si,offset tokens ; search token list
mov dl,0 ; number of items to compare
p147: mov dh,[si] ; get token
cmp dh,al ; same?
jz p148 ; yes
inc si ; point to next token
inc dl
cmp dl,11 ; done?
jnz p147 ; no
jmp p155 ; no hit
p148: ; got a valid character
mov dh,0
mov di,offset modtbl
add di,dx ; got offset into table
mov es:[di],dh ; clear current setting
mov dh,[bx+1] ; get next character
cmp dh,'+' ; is it a plus?
jnz p149 ; no
mov dh,2 ; set it on
jmp p150
p149: cmp dh,'-' ; is it a minus?
jnz p155 ; no
mov dh,1 ; set it off
p150: mov es:[di],dh ; change mod table
p155: inc bx ; point to next char
loop p146 ; done?
p159: ret
p140 endp
p160 proc near ; turn suspend off
push ax
push es
push di
mov ax,40h
mov es,ax
mov di,17h ; point to keyboard flag
mov al,es:[di] ; keyboard state - flag in al
and al,0efh ; turn suspend off
mov es:[di],al ; re-set state
pop di
pop es
pop ax
ret
p160 endp
p180 proc near ; display status of keys
mov ax,realcs ; get real code segment
mov es,ax ; get code seg in es
mov cx,11 ; items to display
mov di,offset modtbl ; point to mod table
mov dx,offset dummy1 ; point to first message
p181:
mov si,dx
mov al,[si] ; get first char of message
cmp al,255 ; no show?
jz p185 ; yes
call p200 ; print key name(s)
push dx
mov al,es:[di]
cmp al,0
jb p182 ; out of range
cmp al,2
jbe p183
p182: mov al,2
p183: push cx
mov cl,4
mov ah,0
rol al,cl ; convert number to message offset
pop cx
mov dx,offset statemsg
add dx,ax
call p200 ; print status message
pop dx ; get part 1 address
p185: add dx,18 ; point to next one
inc di ; point to next status byte
loop p181 ; go back for more...
ret
p180 endp
p200 proc near ; display message
push ax
mov ah,9
int 21h
pop ax
ret
p200 endp
dummy1 db 255,' $' ; key names
capsmsg db 'Caps Lock (U):$'
numlmsg db 'Num Lock (N):$'
dummy2 db 255,' $'
altkmsg db 'Alt key (A):$'
ctrlmsg db 'Ctrl key (C):$'
lshkmsg db 'Left shift (L):$'
rshkmsg db 'Right shift (R):$'
bootmsg db 'Alt-Ctrl-Del (B):$'
cbrkmsg db 'Ctrl-Break (X):$'
suspmsg db 'Suspend (S):$'
statemsg db ' Not affected',10,13,'$' ; status messages
db ' Off ',10,13,'$'
db ' On ',10,13,'$'
copyr db 'KEYMOD - Copyright 1983 Data Base Decisions',10,13,10,13,'$'
install db 'Installing keyboard modifier',10,13,10,13,'$'
realcs dw 0 ; cs of first copy of this program
firstime db 0 ; 0 if repeat, 1 if first time (original)
tokens db 255,'UN',255,'ACLRBXS'; commands
keymod endp
cseg ends
end keymod